const char htmlPage[] = R"html(
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PID控制台</title>
    <style>
        :root {
            color-scheme: only light;
            /* 告诉浏览器只使用浅色模式 */
            background-color: white;
            /* 强制设置根元素背景色 */
        }

        a {
            text-decoration: none;
            user-select: none;
            color: black;
            transition: transform 0.2s ease;
            display: inline-block;
            margin: 0 10px;
        }

        a:active {
            transform: scale(1.3);
        }

        ul {
            list-style: none;
            padding: 0;
            /* 移除默认内边距 */
            margin: 0;
            /* 移除默认外边距 */
        }

        .top {
            font-weight: 600;
            padding: 0 16px;
            height: 60px;
            font-size: 16px;
            background-color: black;
            color: white;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .top .top-left {
            display: flex;
            justify-content: center;
            border: 2px solid white;
            border-radius: 10px;
            height: 30px;
            width: 86px;
        }

        /* 连接状态颜色区分（成功绿色/失败红色） */
        #connect-status.success {
            color: #28a745;
        }

        #connect-status.fail {
            color: #dc3545;
        }

        .pid-module {
            border: 3px solid black;
            margin-bottom: 10px;
        }

        .pid-module ul {
            display: flex;
            font-size: 30px;
            justify-content: space-around;
        }

        /* 选中pid */
        .pid-selected {
            transition: all 0.2s linear;
            border: 5px solid red;
        }

        /* 关键：数值变化特效的基础样式 + 过渡动画 */
        .pid-value {
            display: inline-block;
            /* 让transform生效 */
            transition: all 0.1s linear;
            /* 过渡平滑度 */
        }

        /* 数值变大时的特效样式（放大+颜色强调） */
        .change-effect {
            transform: scale(1.1);
            color: #ff4444;
            font-weight: bold;
        }

        .foot {
            font-size: 16px;
            display: flex;
            position: fixed;
            bottom: 30px;
            width: calc(100% - 60px);
            justify-content: space-between;
            padding: 0 20px;
        }

        .action_button {
            width: 60px;
            border-radius: 50%;
            background-color: black;
            color: white;
            line-height: 60px;
            text-align: center;
            user-select: none;
            transition: transform 0.2s linear;
        }

        .action_button:active {
            background-color: #333;
            transform: scale(1.2);
        }

        /* 底部增加按钮 */
        .add-button {
            font-size: 40px;
        }

        /* 提交pid按钮 */
        .commit-button {
            width: 80px;
            border-radius: 10px;
        }
    </style>
</head>

<body>
    <div class="top">
        <div class="top-left">PID控制台</div>
        <button id="pid-step">pid步进:<span>0.1</span></button>
        <div>连接状态:<span id="connect-status" class="success">成功</span></div>
    </div>
    <div id="main-page">
        <div class="pid-module" id="pid1">
            <div style="color: red;font-size: 16px;font-weight: 1000;">PID1</div>
            <ul id="PID">
                <li>P:<span class="pid-value">0</span></li>
                <li>I:<span class="pid-value">0</span></li>
                <li>D:<span class="pid-value">0</span></li>
            </ul>
            <ul>
                <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
                <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
                <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
            </ul>
        </div>
        <!-- 添加按钮 -->
        <footer class="foot">
            <div class="step-button action_button" id="pid-history">清除</div>
            <div class="commit-button action_button " id="commitButton">提交</div>
            <div class="add-button action_button" id="addPid">+</div>
        </footer>
    </div>

    <script>
        const container = document.getElementById('main-page');//容器对象
        const pid_step = document.getElementById('pid-step');//步进文本
        const pid1 = document.getElementById('pid1');//获取第一个pid模组

        const pid_history = document.getElementById('pid-history');
        const add_button = document.getElementById('addPid');//增加按钮
        const commit_btn = document.getElementById('commitButton');//提交按钮
        let pid_counter = 1;
        let pid_step_value = parseFloat(pid_step.querySelector('span').textContent);//pid步进值
        // pid步进按钮
        pid_step.addEventListener('click', () => {
            switch (pid_step_value) {
                case 0.01:
                    pid_step_value = 0.1;
                    break;
                case 0.1:
                    pid_step_value = 1;
                    break;
                case 1:
                    pid_step_value = 10;
                    break;
                case 10:
                    pid_step_value = 0.01;
                    break;
            }
            pid_step.querySelector('span').textContent = pid_step_value;
        });

        //提交按钮
        commit_btn.addEventListener('click', () => {
            const selectModules = document.querySelector('.pid-selected');
            // console.log(selectModules[0]);
            const PID_Value = selectModules.querySelectorAll('#PID span.pid-value');
            let p_value = PID_Value[0].textContent;
            let i_value = PID_Value[1].textContent;
            let d_value = PID_Value[2].textContent;
            let pidString = `${selectModules.id}/P:${p_value},I:${i_value},D:${d_value}`;
            // console.log(pidString);
            fetch('/pid_commit', {
                method: "POST",
                headers: {
                    "Content-Type": "text/plain"
                },
                body: pidString  // 直接将字符串作为请求体
            })
                .then(response => {
                    if (response.ok) {
                        console.log("字符串发送成功");
                        return response.text();  // 处理服务器响应
                    } else {
                        throw new Error("发送失败，服务器返回错误");
                    }
                })
                .catch(error => {
                    console.error("发送过程出错：", error);
                });
        });

        pid_history.addEventListener('click', () => {
            let clear_status = confirm('你确定要清除所有PID数据吗?');
            console.log(clear_status);
            if (clear_status) {
                fetch('pid_clear', {
                    method: "GET"
                }).then(response => {
                    location.reload(true);//刷新网页
                    console.log("响应成功");
                }).catch(error => {
                    console.log("响应失败")
                })
            }
        })

        // 选中的PID模组特效
        function selectPidModule(module) {
            // 移除所有PID模块的选中状态
            const allModules = document.querySelectorAll('.pid-module');
            allModules.forEach(pid => pid.classList.remove('pid-selected'));

            // 为当前点击的模块添加选中状态
            module.classList.add('pid-selected');
        }

        // 为pid1添加点击事件
        pid1.addEventListener('click', function () {
            selectPidModule(this);
        });

        // 封装特效函数：添加特效类 → 延迟后移除（实现“一闪而过”的效果）
        function triggerValueEffect(element) {
            element.classList.add('change-effect'); // 触发特效
            setTimeout(() => {
                element.classList.remove('change-effect'); // 0.2秒后恢复原样
            }, 100); // 时间与CSS过渡时间一致，确保平滑
        }
        //一个pid模块里实现,点击箭头增加和减少
        function bindParamButtons(pidModule) {
            const decreaseButtons = pidModule.querySelectorAll('.decrease');
            const increaseButtons = pidModule.querySelectorAll('.increase');
            const valueSpans = pidModule.querySelectorAll('#PID span');//获取所有span
            decreaseButtons.forEach((btn, index) => {
                btn.addEventListener('click', () => {
                    const valueElement = valueSpans[index];
                    let number = parseFloat(valueElement.textContent);
                    number -= pid_step_value;
                    number = Math.round(number * (1 / pid_step_value)) / (1 / pid_step_value);
                    valueElement.textContent = number;
                    triggerValueEffect(valueElement);
                });
            });

            increaseButtons.forEach((btn, index) => {
                btn.addEventListener('click', () => {
                    const valueElement = valueSpans[index];
                    let number = parseFloat(valueElement.textContent);
                    number += pid_step_value;
                    number = Math.round(number * (1 / pid_step_value)) / (1 / pid_step_value);
                    valueElement.textContent = number;
                    triggerValueEffect(valueElement);
                });
            });
        }
        bindParamButtons(document.getElementById('pid1'));

        // 增加按钮
        add_button.addEventListener('click', () => {
            pid_counter++;//pid计数器++
            const new_pid = document.createElement('div');
            new_pid.className = 'pid-module';
            new_pid.id = `pid${pid_counter}`
            new_pid.innerHTML = `
                <div style="color: red;font-size: 16px;font-weight: 1000;">PID${pid_counter}</div>
                <ul id="PID">
                    <li>P:<span class="pid-value">0</span></li>
                    <li>I:<span class="pid-value">0</span></li>
                    <li>D:<span class="pid-value">0</span></li>
                </ul>
                <ul>
                    <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
                    <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
                    <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
                </ul>
            `;
            // 将新模块添加到容器中
            container.appendChild(new_pid);
            bindParamButtons(document.getElementById(`pid${pid_counter}`));
            // 为新添加的PID模块添加单选功能
            new_pid.addEventListener('click', function () {
                selectPidModule(this);
            });
        });

        ////////////////////网络状态检查////////////////////
        const connectStatusElem = document.getElementById("connect-status"); // 连接状态元素
        let isConnected = true; // 初始状态：默认连接成功
        let alertShown = false; // 防止重复弹出alert的标记

        function checkServerConnection() {
            // console.log(pid_counter);
            fetch("/heartbeat", {
                method: "GET",
                timeout: 1000 // 请求超时时间（1秒，超时判定为连接失败）
            })
                .then(response => {//连接成功
                    if (!isConnected) {
                        isConnected = true;
                        alertShown = false; // 重置alert标记
                        updateConnectionStatus("成功", "success"); // 更新页面显示
                    }
                })
                .catch(error => {//连接失败
                    if (isConnected) {
                        isConnected = false;
                        updateConnectionStatus("失败", "fail"); // 更新页面显示
                        if (!alertShown) {
                            alert("网络连接已断开！请检查ESP32设备或WiFi连接");
                            alertShown = true;
                        }
                    }
                });
        }

        //更新页面连接状态
        function updateConnectionStatus(text, statusClass) {
            connectStatusElem.classList.remove("success", "fail");
            connectStatusElem.textContent = text;
            connectStatusElem.classList.add(statusClass);
        }
        //解析数据
        function parsePidString(input) {
            const regex = /pid\d+\/[^p]*/g;// 正则表达式匹配字符串
            // 执行匹配并返回结果数组
            const result = input.match(regex) || [];
            // 过滤空字符串
            return result.filter(item => item.trim() !== "");
        }

        window.onload = function () {//加载页面
            fetch('/get_pid_store', {
                method: "GET",
                timeout: 1000 // 请求超时时间（1秒，超时判定为连接失败）
            })
                .then(response => response.text())
                .then(pid_add_data => {
                    if (pid_add_data === "") return; // 无数据时返回
                    // const pid_add_data = "pid1/P:0.1,I:0.2,D:0.3pid2/P:0.3,I:0.2,D:0.1pid3/P:-0.1,I:0.1,D:0.1pid4/P:0.2,I:0.2,D:0.2";//debug使用
                    pid1.remove();//移除之前的pid1
                    const pid_array = parsePidString(pid_add_data);//解析数据
                    // console.log(pid_add_data);//debug
                    // console.log(pid_array);//debug
                    pid_array.forEach((value, index) => {
                        const matches = value.match(/P:(-?[\d.]+),I:(-?[\d.]+),D:(-?[\d.]+)/);
                        const new_p = parseFloat(matches[1]);
                        const new_i = parseFloat(matches[2]);
                        const new_d = parseFloat(matches[3]);
                        //以下为插入新的div代码
                        const new_pid = document.createElement('div');
                        new_pid.className = 'pid-module';
                        new_pid.id = `pid${pid_counter}`;
                        new_pid.innerHTML = `
                            <div style="color: red;font-size: 16px;font-weight: 1000;">PID${pid_counter}</div>
                            <ul id="PID">
                                <li>P:<span class="pid-value">${new_p}</span></li>
                                <li>I:<span class="pid-value">${new_i}</span></li>
                                <li>D:<span class="pid-value">${new_d}</span></li>
                            </ul>
                            <ul>
                                <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
                                <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
                                <li><a href="#!" class="decrease">⬅</a><a href="#!" class="increase">➡</a></li>
                            </ul>
                        `;
                        container.appendChild(new_pid);
                        //为新的div箭头添加和减少的函数
                        bindParamButtons(document.getElementById(`pid${pid_counter}`));
                        // 为新添加的PID模块添加单选功能
                        new_pid.addEventListener('click', function () {
                            selectPidModule(this);
                        });
                        // console.log(value);
                        // console.log(new_p, new_i, new_d);
                        pid_counter++;
                    })
                    pid_counter = pid_counter - 1;
                })
        }
        setInterval(checkServerConnection, 2000);//每隔2000,ms执行一次checkServerConnection函数
    </script>
</body>

</html>
)html";
